[tests] Cover interface method desugaring parity - #12610
Conversation
Replace the stale NativeAOT skip with API-native and forced-desugaring device coverage for static, default, nested, and covariant bridge interface methods across the llvm-ir and trimmable runtime matrix. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Lite
Findings: 1
New issues introduced by this change (2)
| Severity | Finding |
|---|---|
tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs — 💡 suggestion (performance) — AssertInterfaceMethodDexShape calls DexUtils.ContainsClass*… |
|
tests/MSBuildDeviceIntegration/Resources/InterfaceMethodBridgeInvoker.java — invokeStaticMethods() is currently never invoked, so it… |
What changed in this PR
Updates MSBuild device integration coverage to deterministically validate Java 8+ interface method desugaring behavior (native vs companion-class forms) across typemap implementations and runtimes, replacing a stale NativeAOT skip with explicit on-device assertions.
Changes:
- Replaces
SupportDesugaringStaticInterfaceMethodswith a parameterizedInterfaceMethodsMatchDesugaringmatrix (llvm-ir/trimmable × D8/R8 × native/desugared, plus NativeAOT/R8). - Adds a richer Java fixture (static/default methods, nested interface, concrete default override, covariant bridge) and asserts both DEX shape and runtime execution.
- Updates embedded resources and
ResourceDataplumbing to load the new Java sources.
| File | Description |
|---|---|
| tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs | Reworks the test into a matrix, injects runtime calls, and adds DEX-shape assertions for native vs desugared forms. |
| tests/MSBuildDeviceIntegration/Resources/StaticMethodsInterface.java | Removes the older, single static-method fixture. |
| tests/MSBuildDeviceIntegration/Resources/InterfaceMethods.java | New interface fixture with static + default methods and a nested interface. |
| tests/MSBuildDeviceIntegration/Resources/InterfaceMethodPeer.java | New peer type implementing both the main and nested interfaces. |
| tests/MSBuildDeviceIntegration/Resources/ConcreteInterfaceMethodPeer.java | Adds a concrete override calling InterfaceMethods.super to exercise default dispatch. |
| tests/MSBuildDeviceIntegration/Resources/CovariantInterfaceMethods.java | Adds a covariant default-interface method to produce/validate a bridge method shape. |
| tests/MSBuildDeviceIntegration/Resources/InterfaceMethodBridgeInvoker.java | Adds a JNI-invoked bridge runner and (intended) Java-side call sites for retention/parity testing. |
| tests/MSBuildDeviceIntegration/MSBuildDeviceIntegration.csproj | Updates embedded resource glob to include the new interface-method Java fixtures. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/ResourceData.cs | Adds new resource accessors for the added Java fixtures. |
Track the exact normalized package for each matrix case and assert force-stop/uninstall cleanup before and after execution, including failure paths. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Capture dexdump output once per matrix case and execute the Java static-method retention call sites as part of the observed bridge result. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Match class, method, and signature fields within one dexdump method record, keep stderr out of the parsed output, and cover overload and false-positive cases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Require method signatures to immediately follow matching names, pass DEX filenames through ArgumentList, and cover malformed records, repeated classes, and CRLF output. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
/review |
|
✅ Android PR Reviewer completed successfully!
|
There was a problem hiding this comment.
⚠️ Needs Changes
Findings: 0 errors · 1 warning · 1 suggestion
The desugaring matrix is well scoped: it verifies native and companion-class DEX forms across D8/R8 and both runtime typemap paths, while the runtime assertion covers the generated static/default/nested and covariant bridge calls. The new single-capture dexdump path also avoids repeatedly spawning the tool.
The cleanup invoked from finally should not be able to mask the primary test failure, and the direct adb invocation should use the repository's structured-argument pattern. Azure DevOps build 1576513 is still in progress; the checks reported so far have no failures.
Generated by Android PR Reviewer for #12610 · gpt56 · 209.7 AIC · ⌖ 9.1 AIC · ⊞ 25.7K
Comment /review to run again
Run cleanup adb commands with structured arguments and make final cleanup best-effort so it cannot replace a build, DEX, or runtime assertion failure. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
/review |
|
✅ Android PR Reviewer completed successfully!
|
There was a problem hiding this comment.
⚠️ Needs Changes
Findings: 0 errors, 1 warning, 0 suggestions.
The interface-method matrix is comprehensive, the cached DEX parsing is covered by focused regression tests, and the test-only minSdk rewrite cleanly separates native and desugared shapes. One cleanup path still needs adjustment so cleanup failures are suppressed only when preserving an earlier test failure, not after a successful test body.
CI build 1576617 is still in progress with no failures reported at review time; CLA and Android Tools Tests Mac have passed.
Generated by Android PR Reviewer for #12610 · gpt56 · 169.9 AIC · ⌖ 8.86 AIC · ⊞ 25.7K
Comment /review to run again
| "Managed and Java static, default, nested, and covariant bridge interface methods should all execute." | ||
| ); | ||
| } finally { | ||
| TryCleanupInterfaceMethodPackage (proj.PackageName); |
There was a problem hiding this comment.
🤖 finally).
Rule: Challenge exception swallowing


Summary
SupportDesugaringStaticInterfaceMethodsskip with deterministic device coveragePart of #12561.
Investigation
The NativeAOT skip was added by
847c5fe16in March 2026. Trimmable static-method fallback support landed later indaa930d81/ #11050, and the test was subsequently moved to minSdk 24 without revisiting the skip.I reconstructed the pre-#11050 runtime by removing only
TrimmableTypeMapTypeManager.GetStaticMethodFallbackTypesCore()in the child overlay. Both trimmable CoreCLR/D8 and NativeAOT/R8 then failed with:In both failures, DEX contained
Lexample/InterfaceMethods$-CC;.getStaticValue()I. Restoring current production made every case pass, so the skip is stale and no new runtime fix is warranted.The DEX assertions distinguish native interface methods at minSdk 24 from
$-CCcompanions forced with a test-only minSdk 21 rewrite after product validation. Classfile inspection also confirms the covariantObjectmethod isACC_BRIDGE, ACC_SYNTHETIC.Two independent gaps are kept outside this PR:
IJavaObjectconversion). The bridge remains in the fixture as unbound Java and is executed through JNI.Validation
InterfaceMethods_*device cases on API 35 arm64 (emulator-5554):DefaultInterfaceMethodsTestsBindDefaultInterfaceMethodsgit diff --checkBase:
e534500b379a9e394745a2b303a079f42e548de7Head:
fb1f04af53393541e3b8cfff81fd97300daeb933